home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / TERMLIB / TGETSTR.C < prev    next >
C/C++ Source or Header  |  1988-08-23  |  7KB  |  303 lines

  1. /************************************************************************
  2.  *                                      *
  3.  *              Copyright (c) 1982, Fred Fish              *
  4.  *              All Rights Reserved                  *
  5.  *                                      *
  6.  *    This software and/or documentation is released for public          *
  7.  *    distribution for personal, non-commercial use only.          *
  8.  *    Limited rights to use, modify, and redistribute are hereby      *
  9.  *    granted for non-commercial purposes, provided that all          *
  10.  *    copyright notices remain intact and all changes are clearly     *
  11.  *    documented.  The author makes no warranty of any kind with      *
  12.  *    respect to this product and explicitly disclaims any implied    *
  13.  *    warranties of merchantability or fitness for any particular     *
  14.  *    purpose.                                  *
  15.  *                                      *
  16.  ************************************************************************
  17.  */
  18. /* Modified:
  19.  * 30-Apr-86 Mic Kaczmarczik
  20.  *       Use ctype.h macros instead of the function isdigit().
  21.  *       #define index() to be strchr() if VAX C
  22.  */
  23.  
  24.  
  25.  
  26.  
  27. /*
  28.  *  LIBRARY FUNCTION
  29.  *
  30.  *    tgetstr    extract string capability from termcap entry
  31.  *
  32.  *  KEY WORDS
  33.  *
  34.  *    termcap
  35.  *
  36.  *  SYNOPSIS
  37.  *
  38.  *    char *tgetstr(id,area)
  39.  *    char *id;
  40.  *    char **area;
  41.  *
  42.  *  DESCRIPTION
  43.  *
  44.  *    Gets the string capability for <id>, placing it in
  45.  *    the buffer at *area, and advancing *area to point
  46.  *    to next available storage.
  47.  *
  48.  *    For example, if the following capabilities are
  49.  *    in the termcap file:
  50.  *
  51.  *          ZZ=zzzz
  52.  *          YY=yyyyyy
  53.  *          WW=www
  54.  *
  55.  *    then successive calls using YY, ZZ, and WW will
  56.  *    build the following buffer:
  57.  *
  58.  *          yyyyyy0zzzz0www0
  59.  *
  60.  *    The first call will return a pointer to yyyyyy, the
  61.  *    second will return a pointer to zzzz and the third
  62.  *    will return a pointer to www.  Note that each
  63.  *    string is null terminated, as are all C strings.
  64.  *
  65.  *    Characters preceded by the carot character (\136)
  66.  *    are mapped into the corresponding control character.
  67.  *    For example, the two character sequence ^A becomes
  68.  *    a single control-A (\001) character.
  69.  *
  70.  *    The escape character is the normal C backslash and
  71.  *    the normal C escape sequences are recognized, along
  72.  *    with a special sequence for the ASCII escape character
  73.  *    (\033).  The recognized sequences are:
  74.  *
  75.  *          \E   =>  '\033'  (ASCII escape character)
  76.  *          \b   =>  '\010'  (ASCII backspace character)
  77.  *          \f   =>  '\014'  (ASCII form feed character)
  78.  *          \n   =>  '\012'  (ASCII newline/linefeed char)
  79.  *          \r   =>  '\015'  (ASCII carriage return char)
  80.  *          \t   =>  '\011'  (ASCII tab character)
  81.  *          \ddd =>  '\ddd'  (arbitrary ASCII digit)
  82.  *          \x   =>  'x'     (ordinary ASCII character)
  83.  *
  84.  */
  85.  
  86. #include <stdio.h>
  87. #include <ctype.h>
  88. #ifdef VAXC
  89. #define index strchr
  90. #endif
  91.  
  92. extern char *_tcpbuf;          /* Termcap entry buffer pointer */
  93.  
  94.  
  95.  
  96. /*
  97.  *  PSEUDO CODE
  98.  *
  99.  *    Begin tgetstr
  100.  *      Initialize pointer to the termcap entry buffer.
  101.  *      While there is a field to process
  102.  *          Skip over the field separator character.
  103.  *          If this is the entry we want then
  104.  *          If the entry is not a string then
  105.  *              Return NULL.
  106.  *          Else
  107.  *              Transfer string and rtn pointer.
  108.  *          End if
  109.  *          End if
  110.  *      End while
  111.  *      Return NULL
  112.  *    End tgetstr
  113.  *
  114.  */
  115.  
  116. char *tgetstr(id,area)
  117. char *id;
  118. char **area;
  119. {
  120.     char *bp;
  121.     extern char *index();
  122.     static char *decode();
  123.  
  124.     bp = _tcpbuf;
  125.     while ((bp = index(bp,':')) != NULL) {
  126.       if (*++bp == NULL)
  127.           break;
  128.       if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
  129.       if (*bp != NULL && *bp++ != '=') {
  130.           return(NULL);
  131.       } else {
  132.           return(decode(bp,area));
  133.       }
  134.       }
  135.     }
  136.     **area = NULL;
  137.     bp = (*area)++;
  138.     return(bp);
  139. }
  140.  
  141.  
  142.  
  143. /*
  144.  *  INTERNAL FUNCTION
  145.  *
  146.  *    decode   transfer string capability, decoding escapes
  147.  *
  148.  *  SYNOPSIS
  149.  *
  150.  *    static char *decode(bp,area)
  151.  *    char *bp;
  152.  *    char **area;
  153.  *
  154.  *  DESCRIPTION
  155.  *
  156.  *    Transfers the string capability, up to the next ':'
  157.  *    character, or null, to the buffer pointed to by
  158.  *    the pointer in *area.  Note that the initial
  159.  *    value of *area and *area is updated to point
  160.  *    to the next available location after the null
  161.  *    terminating the transfered string.
  162.  *
  163.  *  BUGS
  164.  *
  165.  *    There is no overflow checking done on the destination
  166.  *    buffer, so it better be large enough to hold
  167.  *    all expected strings.
  168.  *
  169.  */
  170.  
  171.  
  172.  
  173. /*
  174.  *  PSEUDO CODE
  175.  *
  176.  *    Begin decode
  177.  *      Initialize the transfer pointer.
  178.  *      While there is an input character left to process
  179.  *          Switch on input character
  180.  *          Case ESCAPE:
  181.  *          Decode and xfer the escaped sequence.
  182.  *          Break
  183.  *          Case CONTROLIFY:
  184.  *          Controlify and xfer the next character.
  185.  *          Advance the buffer pointer.
  186.  *          Break
  187.  *          Default:
  188.  *          Xfer a normal character.
  189.  *          End switch
  190.  *      End while
  191.  *      Null terminate the output string.
  192.  *      Remember where the output string starts.
  193.  *      Update the output buffer pointer.
  194.  *      Return pointer to the output string.
  195.  *    End decode
  196.  *
  197.  */
  198.  
  199. static char *decode(bp,area)
  200. char *bp;
  201. char **area;
  202. {
  203.     char *cp, *bgn;
  204.     char *do_esc();
  205.  
  206.     cp = *area;
  207.     while (*bp != NULL && *bp != ':') {
  208.       switch(*bp) {
  209.       case '\\':
  210.       bp = do_esc(cp++,++bp);
  211.       break;
  212.       case '^':
  213.       *cp++ = *++bp & 037;
  214.       bp++;
  215.       break;
  216.       default:
  217.       *cp++ = *bp++;
  218.       break;
  219.       }
  220.     }
  221.     *cp++ = NULL;
  222.     bgn = *area;
  223.     *area = cp;
  224.     return(bgn);
  225. }
  226.  
  227.  
  228.  
  229. /*
  230.  *  INTERNAL FUNCTION
  231.  *
  232.  *    do_esc    process an escaped sequence
  233.  *
  234.  *  SYNOPSIS
  235.  *
  236.  *    char *do_esc(out,in);
  237.  *    char *out;
  238.  *    char *in;
  239.  *
  240.  *  DESCRIPTION
  241.  *
  242.  *    Processes an escape sequence pointed to by
  243.  *    in, transfering it to location pointed to
  244.  *    by out, and updating the pointer to in.
  245.  *
  246.  */
  247.  
  248.  
  249.  
  250. /*
  251.  *  PSEUDO CODE
  252.  *
  253.  *    Begin do_esc
  254.  *      If the first character is not a NULL then
  255.  *          If is a digit then
  256.  *          Set value to zero.
  257.  *          For up to 3 digits
  258.  *              Accumulate the sum.
  259.  *          End for
  260.  *          Transfer the sum.
  261.  *          Else if character is in remap list then
  262.  *          Transfer the remapped character.
  263.  *          Advance the input pointer once.
  264.  *          Else
  265.  *          Simply transfer the character.
  266.  *          End if
  267.  *      End if
  268.  *      Return updated input pointer.
  269.  *    End do_esc
  270.  *
  271.  */
  272.  
  273. static char *maplist = {
  274.     "E\033b\bf\fn\nr\rt\t"
  275. };
  276.  
  277. char *do_esc(out,in)
  278. char *out;
  279. char *in;
  280. {
  281.     int count;
  282.     char ch;
  283.     extern char *index();
  284.     char *cp;
  285.  
  286.     if (*in != NULL) {
  287.       if (isdigit(*in)) {
  288.       ch = 0;
  289.       for (count = 0; count < 3 && isdigit(*in); in++) {
  290.            ch <<= 3;
  291.            ch |= (*in - '0');
  292.       }
  293.       *out++ = ch;
  294.       } else if ((cp = index(maplist,*in)) != NULL) {
  295.       *out++ = *++cp;
  296.       in++;
  297.       } else {
  298.       *out++ = *in++;
  299.       }
  300.     }
  301.     return(in);
  302. }
  303.